/*
 * @Author      : ZhouQiJun
 * @Date        : 2025-08-09 20:43:22
 * @LastEditors : ZhouQiJun
 * @LastEditTime: 2025-08-10 17:51:52
 * @Description : 绑定地图事件
 */
import { onBeforeUnmount, readonly, ref } from 'vue'

import { getGis } from '@ol/api'
import { Event, type GisKey, KEY } from '@ol/define'
import type { OnEvent } from '@ol/platform'
import { setupEvents } from '@ol/services'
import { type StopRepeat, repeatRun } from 'petite-utils'

/**
 * Vue 3 Hook：为 OpenLayers 地图实例绑定事件，并在组件卸载时可选地自动解绑。
 *
 * 该 Hook 会使用 `repeatRun` 定时尝试绑定事件（防止地图实例尚未初始化时绑定失败），
 * 成功绑定后会将事件解绑函数保存到内部，并根据 `autoClear` 参数在组件卸载时自动调用解绑。
 *
 * @param event - 事件名称（如 `'click'`、`'pointermove'`）
 * @param onEvent - 事件回调函数 `(event, attachment) => void`
 * @param key - 地图实例标识（默认值来自 `@ol/define` 的 `KEY`）
 * @param autoClear - 组件卸载时是否自动解绑事件，默认 `true`
 *
 * @returns 一个对象，包含：
 * - `isOn` - 事件是否已成功绑定（`readonly Ref<boolean>`）
 *
 * @example
 * ```ts
 * const { isOn } = useEvents(
 *   'click',
 *   (event,attachment) => {
 *     console.log('地图被点击', attachment)
 *   },
 *   mapKey
 * )
 * ```
 */
export default function useEvents(event: Event, onEvent: OnEvent, key: GisKey = KEY, autoClear = true) {
  const isOn = ref(false)
  let clearEvents: ReturnType<typeof setupEvents> = null

  // 定时尝试绑定事件
  repeatRun(bindEvents, { interval: 500 })

  // 组件卸载时自动解绑
  if (autoClear) {
    onBeforeUnmount(() => {
      clearEvents?.()
    })
  }

  return {
    isOn: readonly(isOn),
  }

  /**
   * 尝试绑定事件
   */
  function bindEvents(_times: number, stop: StopRepeat) {
    if (clearEvents) return stop()
    const gis = getGis(key)
    if (!gis) return
    clearEvents = setupEvents(event, onEvent, key)
    isOn.value = !!clearEvents
  }
}
